package com.twu.biblioteca;

import com.twu.exception.ShelfException;
import com.twu.exception.MenuException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class BibliotecaApp {
    private Library library;
    private Menu mainMenu;
    private Menu selectionMenu;

    private final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    private ArrayList<Customer> users;
    private Authenticator authenticator;

    public BibliotecaApp() throws MenuException, ShelfException {
        initializeMainMenu();
        initializeSelectionMenu();
        initializeUsers();
        library = new Library();
        authenticator = new Authenticator(users);
    }

    public static void main(String[] args) {
        try {
            BibliotecaApp bibliotecaApp = new BibliotecaApp();
            bibliotecaApp.start();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        } catch (ShelfException e) {
            System.out.println(e.getMessage());
        }
    }

    public void start() throws IOException {
        System.out.println(LibraryConstants.WELCOME_MESSAGE + "\n");
        login();
        userInfo();
        selectMainMenu();
    }

    private void userInfo() {
        System.out.println("User:\n" + authenticator.currentUser().userDetails());
    }

    private void login() throws IOException {
        while (true) {
            System.out.println("Enter your library number: ");
            String number = input.readLine().trim();

            System.out.println("Enter your password: ");
            String password = input.readLine().trim();

            if (authenticator.login(number, password)) {
                break;
            } else {
                System.out.println("Invalid user! Try Again. ");
            }
        }
    }

    private void selectMainMenu() throws IOException {
        while (true) {
            System.out.println(mainMenu.items());
            String selection = input.readLine();
            try {
                int option = mainMenu.select(selection);
                System.out.println(option);
                if (option == 1) {
                    bookService();
                } else if (option == 2) {
                    movieService();
                }
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
            }
        }
    }

    private void bookService() throws IOException {
        System.out.println(library.books());
        displaySelectionMenu();
        String menuOption = input.readLine();
        try {
            int selected = selectionMenu.select(menuOption);
            switch (selected) {
                case 1:
                    checkOutBook();
                    break;
                case 2:
                    returnBook();
                    break;
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        } catch (ShelfException bsfe) {
            System.out.println(bsfe.getMessage());
        }
    }

    private void displaySelectionMenu() {
        System.out.println(selectionMenu.items());
    }

    private void returnBook() throws IOException, ShelfException {
        int number = captureBookNumber();
        System.out.println(library.returnBook(library.returningBook(number), authenticator.currentUser()));
        System.out.println("============================================\n");
    }

    private int captureBookNumber() throws IOException {
        System.out.println("Enter the number of the book: ");
        String num = input.readLine();
        return Integer.parseInt(num);
    }

    private void checkOutBook() throws IOException, ShelfException {
        String bookTitle = captureTitle();
        String authorName = captureAuthorName();
        System.out.println(library.checkOutBook(authenticator.currentUser(), bookTitle, authorName));
        System.out.println("============================================\n");
    }

    private String captureAuthorName() throws IOException {
        System.out.println("Enter the name of the author: ");
        return input.readLine().trim();
    }

    private String captureTitle() throws IOException {
        System.out.println("Enter the Title: ");
        return input.readLine().trim();
    }

    private void movieService() throws IOException {
        System.out.println(library.movies());
        displaySelectionMenu();
        String menuOption = input.readLine();
        try {
            int selected = selectionMenu.select(menuOption);
            switch (selected) {
                case 1:
                    checkOutMovie();
                    break;
                case 2:
                    returnMovie();
                    break;
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        } catch (ShelfException bsfe) {
            System.out.println(bsfe.getMessage());
        }
    }

    private void checkOutMovie() throws IOException, ShelfException {
        String movieTitle = captureTitle();
        System.out.println(library.checkOutMovie(authenticator.currentUser(), movieTitle));
        System.out.println("============================================\n");
    }

    private void returnMovie() throws IOException, ShelfException {
        int number = captureMovieNumber();
        System.out.println(library.returnMovie(library.returningMovie(number), authenticator.currentUser()));
        System.out.println("============================================\n");
    }

    private int captureMovieNumber() throws IOException {
        System.out.println("Enter the number of the movie: ");
        String num = input.readLine();
        return Integer.parseInt(num);
    }

    public void initializeSelectionMenu() throws MenuException {
        selectionMenu = new Menu();
        selectionMenu.add("Checkout");
        selectionMenu.add("Return ");
    }

    public void initializeMainMenu() throws MenuException {
        mainMenu = new Menu();
        mainMenu.add("Go to Books");
        mainMenu.add("Go to Movies");
    }

    private void initializeUsers() {
        users = new ArrayList<Customer>();
        Customer okello = new Customer("John Okello", "BXY-3043");
        okello.setPassword("oke@cust");
        okello.setEmail("jokello@gmail.com");
        okello.setPhoneNumber("+25643223321");
        users.add(okello);
        Customer linda = new Customer("Linda Nantamu", "BTF-9432");
        linda.setPassword("Linda@cust");
        linda.setEmail("nantali@gmail.com");
        linda.setPhoneNumber("+256414055932");
        users.add(linda);
    }

}
